package com.ra.utils;


import com.ra.exception.TaskException;
import com.ra.pojo.Job;
import com.ra.quartz.QuartzDisallowConcurrentExecution;
import com.ra.quartz.QuartzJobExecution;
import org.quartz.*;

import static com.ra.constant.CommonConstant.*;


/**
 * Author : 今晚几点睡_Ada
 * Date: 2023/3/24
 * Time: 14:45
 * 注:
 */

public class ScheduleUtil {

   public static String taskClassName = "TASK_CLASS_NAME";

   public static String taskProperties = "TASK_PROPERTIES";

    private static Class<? extends org.quartz.Job> getQuartzJobClass(Job job) {
        boolean isConcurrent = Integer.valueOf(1).equals(job.getConcurrent());
        return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
    }

    public static TriggerKey getTriggerKey(Integer jobId, String jobGroup) {
        return TriggerKey.triggerKey(taskClassName  + jobId, jobGroup);
    }

    public static JobKey getJobKey(Integer jobId, String jobGroup) {
        return JobKey.jobKey(taskClassName + jobId, jobGroup);
    }

    public static void createScheduleJob(Scheduler scheduler, Job job) throws SchedulerException, TaskException {
        Class<? extends org.quartz.Job> jobClass = getQuartzJobClass(job);
        Integer jobId = job.getId();
        String jobGroup = job.getJobGroup();
        JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build();
        CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
        cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
                .withSchedule(cronScheduleBuilder).build();
        jobDetail.getJobDataMap().put(taskProperties, job);
        //如果有 清除
        if (scheduler.checkExists(getJobKey(jobId, jobGroup))) {
            scheduler.deleteJob(getJobKey(jobId, jobGroup));
        }
        scheduler.scheduleJob(jobDetail, trigger);
        if (job.getStatus().equals(ZERO)) {
            scheduler.pauseJob(ScheduleUtil.getJobKey(jobId, jobGroup));
        }
    }

    /**
     * 按计划处理Cr误射政策
     * @param job
     * @param cb
     * @return
     * @throws TaskException
     */
    public static CronScheduleBuilder handleCronScheduleMisfirePolicy(Job job, CronScheduleBuilder cb)
            throws TaskException {
        //misfire_policy 立即执行错误策略策略
       // 计划执行错误策略（1立即执行 2执行一次 3放弃执行）
        switch (job.getMisfirePolicy()) {
            case ZERO:
                return cb;
            case ONE:
                return cb.withMisfireHandlingInstructionIgnoreMisfires();
            case TWO:
                return cb.withMisfireHandlingInstructionFireAndProceed();
            case THREE:
                return cb.withMisfireHandlingInstructionDoNothing();
            default:
                throw new TaskException("任务失败策略 '" + job.getMisfirePolicy()
                        + "' 不能用于cron调度任务", TaskException.Code.CONFIG_ERROR);
        }
    }
}
